package com.train.daily.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.train.common.enums.impl.BizExceptionEnums;
import com.train.common.exception.GlobalException;
import com.train.common.resp.CommonResp;
import com.train.common.resp.PageResp;
import com.train.daily.dto.carriage.DailyTrainCarriageAddOrEditDTO;
import com.train.daily.dto.carriage.DailyTrainCarriagePageDTO;
import com.train.daily.dto.carriage.DailyTrainCarriageQueryListDTO;
import com.train.daily.mapper.DailyTrainCarriageMapper;
import com.train.daily.po.DailyTrainCarriagePO;
import com.train.daily.resp.carriage.DailyTrainCarriagePageResp;
import com.train.daily.resp.carriage.DailyTrainCarriageQueryListResp;
import com.train.daily.service.DailyTrainCarriageService;
import com.train.openfeign.core.utils.OpenFeignUtils;
import com.train.system.api.TrainApi;
import com.train.system.api.TrainCarriageApi;
import com.train.system.enums.impl.SeatColEnums;
import com.train.system.resp.carriage.TrainCarriageListResp;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.List;

/**
 * @author baitiaojun
 * @description 针对表【dailyTrainCarriage(每日车厢)】的数据库操作Service实现
 * @createDate 2025-03-01 21:20:49
 */
@Service
public class DailyTrainCarriageServiceImpl extends ServiceImpl<DailyTrainCarriageMapper, DailyTrainCarriagePO>
    implements DailyTrainCarriageService {

    private final DailyTrainCarriageMapper dailyTrainCarriageMapper;

    private final TrainCarriageApi trainCarriageFacade;

    private final TrainApi trainApi;

    public DailyTrainCarriageServiceImpl(DailyTrainCarriageMapper dailyTrainCarriageMapper,
                                         @Qualifier("com.train.system.api.TrainCarriageApi") TrainCarriageApi trainCarriageFacade,
                                         @Qualifier("com.train.system.api.TrainApi") TrainApi trainApi) {
        this.dailyTrainCarriageMapper = dailyTrainCarriageMapper;
        this.trainCarriageFacade = trainCarriageFacade;
        this.trainApi = trainApi;
    }

    @Override
    public void addOrEditDailyTrainCarriage(DailyTrainCarriageAddOrEditDTO dailyTrainCarriageAddOrEditDTO) {
        //校验车次是否存在
        CommonResp resp = trainApi.validTrainCodeList(dailyTrainCarriageAddOrEditDTO.getTrainCode());
        if (!OpenFeignUtils.isSuccess(resp)) {
            throw new GlobalException(BizExceptionEnums.EXP_TRAIN_CODE_NOT_EXISTS);
        }

        //校验id是否存在,判断是insert还是update
        if (dailyTrainCarriageAddOrEditDTO.getId() != null) {
            //如果是编辑,需要校验id记录是否存在
            if (!dailyTrainCarriageMapper.existsId(dailyTrainCarriageAddOrEditDTO.getId())) {
                throw new GlobalException(BizExceptionEnums.EXP_DAILY_TRAIN_CARRIAGE_NOT_EXISTS);
            }

            //查询该日同车次下不同车厢和箱号的映射关系
            List<DailyTrainCarriageAddOrEditDTO> idCarriageList = dailyTrainCarriageMapper.getIdCodeList(dailyTrainCarriageAddOrEditDTO);
            if (CollectionUtil.isEmpty(idCarriageList)) {
                throw new GlobalException(BizExceptionEnums.EXP_DAILY_TRAIN_CARRIAGE_NOT_EXISTS);
            }

            //过滤同车次下被更新的车厢, 仅收集同车次的车厢
            List<Integer> carriageIndexList = idCarriageList.parallelStream()
                    .filter(item -> !item.getId().equals(dailyTrainCarriageAddOrEditDTO.getId()))
                    .map(DailyTrainCarriageAddOrEditDTO::getIndex)
                    .toList();

            //检查该日同车次中更被新车厢的箱号是否和其他箱号重合
            boolean exists = carriageIndexList.contains(dailyTrainCarriageAddOrEditDTO.getIndex());
            if (exists) {
                throw new GlobalException(BizExceptionEnums.EXP_DAILY_TRAIN_CARRIAGE_EXISTS);
            }
        } else {
            //查询该日里同一车次的该车厢是否存在
            if (dailyTrainCarriageMapper.existsDailyTrainCarriage(dailyTrainCarriageAddOrEditDTO)) {
                throw new GlobalException(BizExceptionEnums.EXP_DAILY_TRAIN_CARRIAGE_EXISTS);
            }
        }

        //生成列数和座位数
        SeatColEnums[] seatColEnums = SeatColEnums.getByType(dailyTrainCarriageAddOrEditDTO.getSeatType());
        int colCount = seatColEnums.length;
        int seatCount = dailyTrainCarriageAddOrEditDTO.getRowCount() * colCount;

        DailyTrainCarriagePO trainCarriagePO = BeanUtil.copyProperties(dailyTrainCarriageAddOrEditDTO, DailyTrainCarriagePO.class);
        trainCarriagePO.setColCount(colCount);
        trainCarriagePO.setSeatCount(seatCount);
        boolean isSaved = this.saveOrUpdate(trainCarriagePO);
        if (!isSaved) {
            throw new GlobalException(BizExceptionEnums.EXP_ADD_DAILY_TRAIN_CARRIAGE);
        }
    }

    @Override
    public PageResp<DailyTrainCarriagePageResp> pageList(DailyTrainCarriagePageDTO dailyTrainCarriagePageDTO) {
        return dailyTrainCarriageMapper.pageList(dailyTrainCarriagePageDTO);
    }

    @Override
    public void remove(Long id) {
        boolean isRemoved = this.removeById(id);
        if (!isRemoved) {
            throw new GlobalException(BizExceptionEnums.EXP_REMOVE_DAILY_TRAIN_CARRIAGE);
        }
    }

    @Override
    public void generateDailyCarriage(String date, List<String> trainCodes) {
        //基础数据查询所有车厢
        CommonResp resp = trainCarriageFacade.getTrainCarriageListByTrainCodes(trainCodes);

        //转换类型
        List<TrainCarriageListResp> trainCarriageList = OpenFeignUtils.getResultList(resp, TrainCarriageListResp.class);
        if (CollectionUtil.isEmpty(trainCarriageList)) {
            throw new GlobalException(BizExceptionEnums.EXP_TRAIN_CARRIAGE_NOT_EXISTS);
        }


        //删除当天车站
        if (dailyTrainCarriageMapper.existsDailyTrainCarriage(LocalDate.parse(date), trainCodes)) {
            int isDeleted = dailyTrainCarriageMapper.deleteTrainCarriages(LocalDate.parse(date), trainCodes);
            if (isDeleted == 0) {
                throw new GlobalException(BizExceptionEnums.EXP_ADD_DAILY_TRAIN_CARRIAGE);
            }
        }

        //重新添加当天车次
        List<DailyTrainCarriagePO> dailyTrainCarriagePOS = BeanUtil.copyToList(trainCarriageList, DailyTrainCarriagePO.class);
        dailyTrainCarriagePOS.forEach(dailyTrainCarriagePO -> dailyTrainCarriagePO.setDate(LocalDate.parse(date)));
        boolean isSaved = this.saveBatch(dailyTrainCarriagePOS);
        if (!isSaved) {
            throw new GlobalException(BizExceptionEnums.EXP_ADD_DAILY_TRAIN_CARRIAGE);
        }
    }

    @Override
    public List<DailyTrainCarriageQueryListResp> queryTrainCarriageList(DailyTrainCarriageQueryListDTO dto) {
        return dailyTrainCarriageMapper.selectTrainCarriageList(dto);
    }
}




